/*  

Cafechess Library: Cover basic chess programming needs, like GUI, Engine integration, 
FEN and PGN parsing.

                 \\|//
                 (o o)
--------------ooO-(_)-Ooo----------------------------------
Copyright (C) 2009  By Gregory A. Prentice Snoqualmie, WA
                    www.cafechess.org
                    cafechess@comcast.net
                      Oooo
--------------oooO----(  )---------------------------------
              (  )    (_/
               \_)

Microsoft Public License (Ms-PL)
               
Revisions:

Author        Date    Description:

*/
using System;
using System.Collections;
using Cafechess.Chess.General;
using Cafechess.Chess.Parsers;
namespace Cafechess.Chess.Validation
{
  #region ValidationEngine
  /// <summary>
  /// Defines the interfaces needed to determine the
  /// rules for a game of chess or chess variant.
  /// </summary>
  public interface IValidation
  {
    /// <summary>
    /// Request that a piece be moved on the board.
    /// </summary>
    /// <param name="piece">Piece to move</param>
    /// <param name="fromSquare">Source square in algerbraic notation</param>
    /// <param name="toSquare">Destination square in algerbraic notation</param>
    /// <returns></returns>
    bool Move(Pieces piece, string fromSquare, string toSquare);
    /// <summary>
    /// Sends an algerbraic string and expects the engine to determine the
    /// source and destination squares.
    /// </summary>
    /// <param name="algebraic"></param>
    /// <returns></returns>
    bool Move(string algebraic);
    /// <summary>
    /// Used to register event handlers for validation events such as king checks etc.
    /// </summary>
    /// <param name="ievents"></param>
    void AddEvents(IValidationEvents ievents);
    /// <summary>
    /// Used to remove event handlers.
    /// </summary>
    /// <param name="ievents"></param>
    void RemoveEvents(IValidationEvents ievents);
    /// <summary>
    /// Add events used to signal to the UI that it must change it's appearance.
    /// </summary>
    /// <param name="ievents"></param>
    void AddEvents(IValidationUIEvents ievents);
    /// <summary>
    /// Remove UI events.
    /// </summary>
    /// <param name="ievents"></param>
    void RemoveEvents(IValidationUIEvents ievents);
    /// <summary>
    /// Used to retrieve the position events interfaces used for parsing
    /// mainly fen notation.
    /// </summary>
    IPositionEvents PositionEvents{get;}
    /// <summary>
    /// Retrieve the algerbraic notation.
    /// </summary>
    string Notation{get;}
    /// <summary>
    /// Retrieves the full algerbraic notation.
    /// </summary>
    string FullNotation{get;}
    /// <summary>
    /// Retrieves the current FEN string representing the board position.
    /// </summary>
    string FenNotation{get;set;}
    /// <summary>
    /// Used to determine the formatting string of the getter for the FenNotation property.
    /// The standard format is: 
    /// <code>
    /// "{0} {1} {2} {3} {4} {5}" where each represents:
    ///   {0} the board / piece layout.
    ///   {1} color to move
    ///   {2} castling
    ///   {3} enpasant
    ///   {4} half move
    ///   {5} full move
    ///</code>
    /// </summary>    
    string FenFormat{set;}
    /// <summary>
    /// Square a piece moved to.
    /// </summary>
    string MovedTo{get;set;}
    /// <summary>
    /// Square a piece moved from.
    /// </summary>
    string MovedFrom{get;set;}
    /// <summary>
    /// Retreive our set the color to move flag.  True == white.
    /// </summary>
    bool SideToMove{get;set;}
    /// <summary>
    /// Used to determine if the last move made was valid and thus our
    /// public state has changed.
    /// </summary>
    bool IsValidMove{get;set;}
    /// <summary>
    /// Used to turn on and off validation.  When turned off the Move() routines
    /// should always return true and IsValidMoves should also be set to true.
    /// Mainly used when you want to edit the graphical interfaces / position and
    /// don't want to validate the moves until you are done.  Usually then you parse
    /// a fen string before turning validation back on to sync the UI up with the validator.
    /// </summary>
    bool IsValidating{ get; set; }
    /// <summary>
    /// Retrieves a bit array of all squares a color is attacing.
    /// </summary>
    /// <param name="color"></param>
    /// <returns></returns>
    BitArray Attacks(bool sideToMove);
    /// <summary>
    /// Retrieves a bit array of the squares a piece could move to on
    /// an empty board..
    /// </summary>
    /// <param name="piece"></param>
    /// <param name="square"></param>
    /// <returns></returns>
    BitArray Moves(Pieces piece, int square);

    /// <summary>
    /// Returns an array of values that represent how many pieces are attacking
    /// a particular square.
    /// </summary>
    /// <returns></returns>
    int[] WeightWeakSquares();
  }

  /// <summary>
  /// Interface used to define the events that must be handled by the class
  /// using the IValidation interface to ensure all interaction between the
  /// two are communicated correctly.
  /// </summary>
  public interface IValidationEvents
  {
    /// <summary>
    /// This event is fired when the validator needs to know which piece you are
    /// promotting a pawn to.
    /// </summary>
    /// <param name="color">True then white is promoting else black.</param>
    /// <param name="square">algebraic square piece is promoting to</param>
    /// <param name="piece">A reference where you assign the promotion piece</param>
    void Promotion(bool color, string square, ref Pieces piece);
    /// <summary>
    /// Event is fired when the king has been check mated.
    /// </summary>
    void KingIsMated();
    /// <summary>
    /// Event is fired when the king has been stale mated.
    /// </summary>
    void KingIsStaleMated();
    /// <summary>
    /// Event is fired when the king is in check.
    /// </summary>
    void KingIsInCheck();
    /// <summary>
    /// Event is fired when the king is not in check.
    /// </summary>
    void KingIsFree();
    /// <summary>
    /// Event is fired before we make a move.
    /// </summary>
    /// <param name="piece">piece where moving</param>
    /// <param name="from">source square</param>
    /// <param name="to">destination square</param>
    void BeforeMove(Pieces piece, string from, string to);
    /// <summary>
    /// Event is fired after we make a move.
    /// </summary>
    /// <param name="piece">piece where moving</param>
    /// <param name="from">source square</param>
    /// <param name="to">destination square</param>
    void AfterMove(Pieces piece, string from, string to);
  }
  /// <summary>
  /// Interface used to define events that a UI must handle to show any piece movement that
  /// the validation engine requires to reflect any public changes to the board
  /// state.  Such as castling the user only moves the king but the UI needs to move the
  /// rook as well.
  /// </summary>
  public interface IValidationUIEvents
  {
    /// <summary>
    /// Validation fires this event when it needs the gui to update piece/square
    /// display information.  Uses algebraic square notation ie a4, d5, h5.
    /// </summary>
    /// <param name="op">Are moving, adding, or deleting a piece</param>
    /// <param name="FromSquare">When adding or deleting this is the location, when moving 
    /// it is the source square.</param>
    /// <param name="ToSquare">When moving this is the destination square of the piece.</param>
    /// <param name="piece"></param>
    void UpdateBoard(Operation op, string FromSquare, string ToSquare, Pieces piece);
    /// <summary>
    /// Asks the gui to redraw itself as something has changed such as castling.
    /// </summary>
    void RedrawBoard();
  }
  #endregion

}
